package com.example.testdemo.db.reflex;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *
 * </p>
 *
 * @author 永健
 * @since 2020-03-28 16:54
 */
public class Reflex {


    /**
     * <p>
     * 反射对象获取泛型
     * </p>
     *
     * @param clazz 对象
     * @param index 泛型所在位置
     * @return Class
     */
    public static Class<?> getSuperClassGenericType(final Class<?> clazz, final int index) {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType)) {
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0) {
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            return Object.class;
        }
        return (Class<?>) params[index];
    }


    /**
     * 获取实例的有值的字段和值
     * [0]=属性名字
     * [1]=值
     *
     * @param object
     * @return List<String>
     */
    public static List<String> getPropertiesAndValuesIsNotNull(Object object) {
        Class<?> aClass = object.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        List<String> list = new ArrayList<>();

        StringBuffer clumn = new StringBuffer();
        StringBuffer values = new StringBuffer();

        for (Field field : declaredFields) {

            Object val = getVal(object, aClass, field);
            if (val != null) {
                clumn.append(field.getName());
                values.append(val);
            }
        }
        return list;
    }


    /**
     * 获取类的所有属性
     *
     * @param aClass
     * @return
     */
    public static List<String> getPropertis(Class<?> aClass) {
        Field[] declaredFields = aClass.getDeclaredFields();
        List<String> list = new ArrayList<>();
        for (Field field : declaredFields) {
            list.add(field.getName());
        }
        return list;
    }

    /**
     * 获取读取的对像有值的key value
     *
     * @param object
     * @return
     */
    public static Map<String, Object> getKeyValues(Object object) {

        Class<?> aClass = object.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();

        Map<String, Object> param = new HashMap<>();
        for (Field field : declaredFields) {
            Object val = getVal(object, aClass, field);
            if (val != null) {
                param.put(field.getName(), val);

            }
        }
        return param;
    }


    /**
     * 获取某个属性的值
     * @param object
     * @param aClass
     * @param field
     * @return
     */
    private static Object getVal(Object object, Class<?> aClass, Field field) {

        String fieldName = field.getName();
        String first = fieldName.substring(0, 1).toUpperCase();
        String getName = "get" + first + fieldName.substring(1);
        try {
            Method method = aClass.getMethod(getName, null);
            Object val = method.invoke(object, null);
            if (val != null) {
                return val;
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            System.out.println("没有此方法：" + getName + "()");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取属性类型
     * @param aClass
     * @param fileName
     * @return
     */
    public static Class<?> getFieldType(Class<?> aClass, String fileName) {
        try {
            Field field = aClass.getDeclaredField(fileName);
            return field.getType();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return null;
    }
}
